home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
gcc
/
ixemulsrc.lha
/
ixemul-41.4
/
library
/
kern_descrip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-28
|
9KB
|
379 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* kern_descrip.c,v 1.1.1.1 1994/04/04 04:30:42 amiga Exp
*
* kern_descrip.c,v
* Revision 1.1.1.1 1994/04/04 04:30:42 amiga
* Initial CVS check in.
*
* Revision 1.2 1992/07/04 19:19:04 mwild
* add support for F_INTERNALIZE/F_EXTERNALIZE, which are used by IXPIPE
* and execve().
*
* Revision 1.1 1992/05/14 19:55:40 mwild
* Initial revision
*
*
* Since the code originated from Berkeley, the following copyright
* header applies as well. The code has been changed, it's not the
* original Berkeley code!
*/
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution is only permitted until one year after the first shipment
* of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
* binary forms are permitted provided that: (1) source distributions retain
* this entire copyright notice and comment, and (2) distributions including
* binaries display the following acknowledgement: This product includes
* software developed by the University of California, Berkeley and its
* contributors'' in the documentation or other materials provided with the
* distribution and in all advertising materials mentioning features or use
* of this software. Neither the name of the University nor the names of
* its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)kern_descrip.c 7.16 (Berkeley) 6/28/90
*/
#define KERNEL
#include "ixemul.h"
#include "kprintf.h"
extern int __sync_write (), __write ();
/*
* Descriptor management.
*/
/*
* System calls on descriptors.
*/
/* ARGSUSED */
int
getdtablesize ()
{
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return NOFILE;
}
/*
* Duplicate a file descriptor.
*/
/* ARGSUSED */
int
dup (unsigned i)
{
struct file *fp;
int fd, error;
if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
{
errno = EBADF;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
if (error = ufalloc (0, &fd))
{
errno = error;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
u.u_ofile[fd] = fp;
u.u_pofile[fd] = u.u_pofile[i] &~ UF_EXCLOSE;
fp->f_count++;
if (fd > u.u_lastfile) u.u_lastfile = fd;
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return fd;
}
/*
* Duplicate a file descriptor to a particular value.
*/
/* ARGSUSED */
int
dup2 (unsigned i, unsigned j)
{
register struct file *fp;
int error;
if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
{
errno = EBADF;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
if (j < 0 || j >= NOFILE)
{
errno = EBADF;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
if (i == j) return (int)j;
ix_lock_base ();
if (u.u_ofile[j] && u.u_ofile[j]->f_close)
u.u_ofile[j]->f_close (u.u_ofile[j]);
u.u_ofile[j] = fp;
u.u_pofile[j] = u.u_pofile[i] &~ UF_EXCLOSE;
fp->f_count++;
if (j > u.u_lastfile)
u.u_lastfile = j;
ix_unlock_base ();
/*
* dup2() must suceed even though the close had an error.
*/
errno = 0; /* XXX */
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return (int)j;
}
/*
* The file control system call.
*/
/* ARGSUSED */
int
fcntl(unsigned fdes, int cmd, int arg)
{
register struct file *fp;
register char *pop;
int i, error;
/* F_INTERNALIZE doesn't need a valid descriptor. Check for this first */
if (cmd == F_INTERNALIZE)
{
if (error = ufalloc (0, &i))
{
errno = error;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
fp = (struct file *) arg;
u.u_ofile[i] = fp;
u.u_pofile[i] = 0;
fp->f_count++;
return i;
}
if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
{
errno = EBADF;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
pop = &u.u_pofile[fdes];
switch (cmd)
{
case F_DUPFD:
if (arg < 0 || arg >= NOFILE)
{
errno = EINVAL;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
if (error = ufalloc (arg, &i))
{
errno = error;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
ix_lock_base ();
u.u_ofile[i] = fp;
u.u_pofile[i] = *pop &~ UF_EXCLOSE;
fp->f_count++;
ix_unlock_base ();
if (i > u.u_lastfile) u.u_lastfile = i;
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return (int)i;
case F_GETFD:
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return *pop & 1;
case F_SETFD:
*pop = (*pop &~ 1) | (arg & 1);
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return 0;
case F_GETFL:
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return OFLAGS(fp->f_flags);
case F_SETFL:
arg &= FCNTLFLAGS;
if (fp->f_type == DTYPE_FILE)
{
fp->f_flags = arg;
if (fp->f_write) fp->f_write = (arg & O_FSYNC) ? __sync_write :__write;
}
errno = 0;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return 0;
case F_EXTERNALIZE:
return (int)fp;
default:
errno = EINVAL;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
return -1;
}
/* NOTREACHED */
}
/*
* Return status information about a file descriptor.
*/
/* ARGSUSED */
int
fstat (unsigned fdes, struct stat *sb)
{
register struct file *fp;
if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
{
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
errno = EBADF;
return -1;
}
/* if this file is writable, then it's quite probably that the stat buffer
information stored at open time is no longer valid. So if the file really
is a file, update that information */
if ((fp->f_flags & FWRITE) && fp->f_type == DTYPE_FILE)
__fstat (fp);
*sb = fp->f_stb;
return 0;
}
/*
* Allocate a user file descriptor.
*/
int
ufalloc(int want, int *result)
{
for (; want < NOFILE; want++)
{
if (u.u_ofile[want] == NULL)
{
u.u_pofile[want] = 0;
if (want > u.u_lastfile) u.u_lastfile = want;
*result = want;
return 0;
}
}
return EMFILE;
}
/*
* Allocate a user file descriptor
* and a file structure.
* Initialize the descriptor
* to point at the file structure.
*/
int
falloc(struct file **resultfp, int *resultfd)
{
register struct file *fp;
int error, i;
if (error = ufalloc(0, &i))
return (error);
ix_lock_base ();
if (ix.ix_lastf == 0)
ix.ix_lastf = ix.ix_file_tab;
for (fp = ix.ix_lastf; fp < ix.ix_fileNFILE; fp++)
if (fp->f_count == 0)
goto slot;
for (fp = ix.ix_file_tab; fp < ix.ix_lastf; fp++)
if (fp->f_count == 0)
goto slot;
/* YES I know.. it's not optimal, we should resize the table...
* unfortunately all code accessing file structures will then have
* to be changed as well, and this is a job for later improvement,
* first goal is to get this baby working... */
ix_panic ("ixemul.library file table full!");
error = ENFILE;
goto do_ret;
slot:
u.u_ofile[i] = fp;
fp->f_name = 0;
fp->f_count = 1;
fp->f_type = 0; /* inexistant type ;-) */
fp->f_async_buf = 0;
fp->f_async_len = 0;
ix.ix_lastf = fp + 1;
if (resultfp)
*resultfp = fp;
if (resultfd)
*resultfd = i;
error = 0;
do_ret:
ix_unlock_base();
return error;
}
/*
* Apply an advisory lock on a file descriptor.
*/
/* ARGSUSED */
int
flock (int fdes, int how)
{
return 0; /* always succeed */
}